import { Compiler, Plugin } from "webpack";
import { RawSource } from "webpack-sources";

// 为了能让它有类型提示，我们让它实现 webpack 的 Plugin 的类型接口
class WebpackSizePlugin implements Plugin {
	// 定义初始化参数
	options: any;
	PLUGIN_NAME: string = "WebpackSizePlugin";

	// 在这里获取plugin的参数，把参数挂载到this.options上
	constructor(options: any) {
		this.options = options;
	}

	// vscode会提示如果要实现Plugin，需要apply方法
	// 参数是compiler，类型是webpack的Compiler
	apply(compiler: Compiler) {
		// 保存最终文件输出路径
		const outputOptions = compiler.options.output;

		// 在这个函数中我们就可以读取和操作本次编译产生的结果
		compiler.hooks.emit.tap(this.PLUGIN_NAME, compilation => {
			// 所有的编译结果都可以通过compilation.assets取到
			// 它是一个对象，key是编译结果的各个文件名，value 是各个文件的内容
			const assets = compilation.assets;

			// 为了保存编译信息，初始化空对象
			const buildSize = {} as any;

			// 定义统计结果total
			let total = 0;

			// 遍历每个文件
			const files = Object.keys(assets);
			for (const file of files) {
				// assets的文件每一个值是一个RawSource对象，它有一个size方法，可以统计出文件内容包含的字符数
				const size = assets[file].size();
				buildSize[file] = size;
				total += size;
			}
			console.log("Build Size: ", buildSize);
			console.log("total Size: ", total);
			buildSize.total = total;

			// 想要webpack生成一个size.json文件来存放buildSize的内容
			// key 是文件名，value值是一个RawSource对象
			assets[outputOptions.publicPath + "/" + this.options.fileName] = new RawSource(
				JSON.stringify(buildSize, null, 4)
			);
		});
	}
}

module.exports = WebpackSizePlugin;
